import re,json,random,time,functools,requests


from tools.captcha.captcha import captcha
from tools.myredis import r
from tools.comm import sendMsg
from tools.myjwt import mjwt
from flask import Blueprint,request,jsonify,make_response,redirect
from application.models.users.user import *
user_blue = Blueprint("userblue",__name__)

# @user_blue.route("/reg")
# def reg():
#     res = User.query.all()
#     print(res)
#     return '欢迎使用flask'

# 权限认证
# def islogin(func):
#     @functools.wraps(func)
#     def wrapper():
#         # func()
#         # 权限验证判断，如果有问题返回
#         return func()
#     return wrapper

# def islogin(type):
#     def pemistion(func):
#         @functools.wraps(func)
#         def wrapper():
#             func()
#             if type ==1:
#                 return redirect("http://www.baidu.com")
#             else:
#                 return redirect("http://www.jd.com")
#         return wrapper
#     return pemistion
#
# #测试
#
# @user_blue.route("/test")
# @islogin(1)
# def test():
#     print("执行test")
#     return jsonify({"code":200,'mes':'mes'})
#
# #获取图片验证码
# @user_blue.route("/getcode")
# @islogin(2)
# def getcode():
#     print("getcode")

#

# 测试
import pymysql
from tools.comm import get_ali_object

@user_blue.route("/test")
def test():
    orderno = '123'
    pay = get_ali_object()
    # 生成支付的url
    query_params = pay.direct_pay(
        subject="test",  # 商品简单描述
        out_trade_no=str(orderno),  # 用户购买的商品订单号（每次不一样） 20180301073422891
        total_amount=float(100.00),  # 交易金额(单位: 元 保留俩位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
    return jsonify({
        "code":200,
        "url":pay_url
    })


# 获取图片验证码
@user_blue.route("/getcode")
def getcode():
    # 生成图片验证码,text文字，image图片流
    name,text,image = captcha.generate_captcha()
    # 从页面获取uuid作为redis key
    uuid = str(request.args.get('uuid'))
    # 存入redis
    r.str_add(uuid,str(text),60)
    # 以流的方式生成图片验证码
    res = make_response(image)
    res.headers["Content-Type"] = "image/jpg"
    return res

# 发送短信验证码
@user_blue.route("/sendSmsCode",methods=['POST'])
def sendSmsCode():
    data = request.data
    if data:
        data = json.loads(data)
    # 获取3个参数
    uuid = data["uuid"]
    piccode = data['piccode']
    mobile = data['mobile']
    # 通过uuid查询redis
    value = r.str_get(uuid)
    if value:
        # 两个验证码对比，如果成功调用短信平台发送短信
        if piccode.lower() == value.lower():
            # 验证1分钟内只能发一次
            mcode = r.str_get(mobile)
            if mcode:
                return jsonify({
                    "code":10011,
                    "mes":"一分钟内不能重复发"
                })
            # 生成5位随机数
            scode = random.randint(10000,99999)
            # 调用短信平台
            flag = sendMsg(mobile,scode)
            if flag == True:
                # 存入redis
                r.str_add(mobile,scode,60)
                # 删除图片验证码
                r.del_str(uuid)
                # 返回结果
                return jsonify({
                    "code":200,
                    "mes":"发送成功"
                })
            else:
                return jsonify({
                    "code":10013,
                    "mes":"发送验证码失败"
                })
        else:
            return jsonify({
                "code":10012,
                "mes":"图片验证码错误"
            })
        # 失败返回错误信息
    else:
        return jsonify({
            "code":10010,
            "mes":"图片验证码不存在"
        })

# 注册登陆接口
@user_blue.route("/reg",methods=['POST'])
def login():
    # 获取参数，手机号，验证码
    data = request.data
    if data:
        data = json.loads(data)
        # 获取3个参数
        mcode = data['code']
        mobile = data['mobile']
        # 根据手机号去redis获取验证码
        code = r.str_get(mobile)
        if code:
            # 验证码是否相同,如果不相同返回错误信息
            if int(code) == int(mcode):
                # 如果相同查询数据库user表
                # 如果存在返回用户信息
                # 如果不存在写入用户表
                user = User.query.filter_by(User.mobile==mobile).first()
                if user:
                    # 删除redis中的验证码
                    r.del_str(mobile)
                else:
                    u = User(mobile=mobile)
                    db.session.add(u)
                    db.session.commit()
                    user = User.query.filter_by(User.mobile == mobile).first()
                    # 用用户信息生成jwt token
                    token = mjwt.jwt_encode(data={"data":{"uid":user.id,"exp":int(time.time())}})
                    return jsonify({
                        "code":200,
                        "token":token,
                        "userid":user.id
                    })
                    # 返回给页面
            else:
                return jsonify({
                    "code":10020,
                    "mes":"验证码错误"
                })
        else:
            return jsonify({
                "code":10021,
                "mes":"登陆成功"
            })

# 获取weibo地址
@user_blue.route('/getwxurl')
def getwburl():
    client_id = '3674019597'
    redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
    url = "https://api.weibo.com/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s" % (
    client_id, redirect_uri)
    return jsonify({'code': 200, 'url': url})


# weibo回调接口
@user_blue.route('/weiboCallback/')
def weiboCallback():

    # 获取code
    code = request.args.get('code')

    #向access-token接口发起post请求
    data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
            "grant_type": "authorization_code",
            'redirect_uri': "http://127.0.0.1:8000/user/weiboCallback/", 'code': code}
    res = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
    # 解析参数，tolken，uid
    mes = json.loads(res.text)
    token = mes['access_token']
    uid = mes['uid']

    # 查询三方登录中uid是否存在，如果存在，查询用户表，用用户信息生成token跳转到vue页面
    # sf = SfLogin.query.filter(SfLogin.uid == uid).first()
    # if sf:
    #     user = User.query.filter(User.id == sf.userid).first()
    #     data={'data':{"userid":user[0],"exp":int(time.time())}}
    #     token = mjwt.jwt_encode(data)
    #     return redirect('http://localhost:8080/#/upateToken?userid='+str(user[0])+"&token="+token)

    sql = "select user.id from user inner join sf_login on user.id=sf_login.userid where sf_login.uid='%s'" % (uid)
    user = db.session.execute(sql)
    # orm查询
    # 判断是否查询到
    if user:
        for i in user:
            data = {'data': {"userid": i[0], "exp": int(time.time())}}
            token = mjwt.jwt_encode(data)
            return redirect('http://localhost:8080/#/upateToken?userid=' + str(i[0]) + "&token=" + token)
    # 不存在跳转到vue绑定页面，token uid传递过去
    return redirect('http://localhost:8080/#/bindMobile?uid=' + uid + "&token=" + token)

# 绑定手机号
@user_blue.route('/bindMobile',methods=['POST'])
def bindMobile():
    data = json.loads(request.data)
    mobile = data['mobile']
    uid = data.get('uid')
    token = data['token']
    # 先查询用户表，如果手机号存在
    user = User.query.filter(User.mobile == mobile).first()
    if not user:
        # 添加用户
        u= User(mobile=mobile,nikename=mobile)
        db.session.add(u)
        db.session.commit()
        # 获取用户信息
        user = User.query.filter(User.mobile == mobile).first()

    sfuser = SfLogin(userid=user.id, webfrom='wb', uid=uid, token=token)
    db.session.add(sfuser)
    db.session.commit()
    # 如果不存在，写入user表
    # 获取userid，写入三方登录，生成token返回
    data = {"data": {"userid": user.id, "exp": int(time.time())}}
    token = mjwt.jwt_encode(data)
    return jsonify({
        "userid":str(user.id),
        "token":token
    })
    #return redirect("http://localhost:8000/#/updataToken?userid=" +user.id + "&token=" + token)


# 购买vip生成订单
@user_blue.route("/buy",methods=['POST'])
def buy():
    # 获取参数
    data = json.loads(request.data)
    userid = data['userid']
    year = data['year']
    money = 200
    tmoney = money * int(year)
    # 生成订单号
    order_no = str(int(time.time())) + str(userid) + str(random.randint(100,999))
    # 写入vip记录表
    viprecord = VipRecord(order_no=order_no,userid=userid,year=year,money=money,active_money=tmoney,status=1)
    db.session.add(viprecord)
    db.session.commit()
    # 支付，返回支付url
    pay = get_ali_object()
    # 生成支付的url
    query_params = pay.direct_pay(
        subject="test", # 商品简单描述
        out_trade_no = str(order_no),  # 用户购买的商品订单号（每次不一样）
        total_amount=float(1.00)  # 交易金额（单位：元，保留两位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址
    return jsonify({
        "code":200,
        "url":pay_url
    })


@user_blue.route("/callback")
def callback():
    # 接收参数
    data = request.args
    datames = {k:v for k,v in data.items()}
    # 删除字典中key为sign的记录
    sign = datames.pop('sign')
    print(">>>>>>>>>>>sign")
    # 鉴权 订单号 流水号
    pay = get_ali_object()
    flag = pay.verify(datames,sign)
    print(flag)
    if flag == True:
        # 订单号
        transaction_no = datames['trade_no']
        # 支付宝流水号
        order_no = datames['out_trade_no']
        # 事务处理
        try:
            # 订单号更新订单表
            record = VipRecord.query.filter(VipRecord.order_no==order_no).first()
            record.status=2
            record.transaction_no=transaction_no
            db.session.add(record)
            # 更新用户表
            User.query.filter(User.id==record.userid).updata({"level":2})
            # 更新vip表
            vip = Vip.query.filter(Vip.userid==record.userid,status=1).first()
            if vip is not None:
                # 结束时间+购买权限
                etime = vip.e_time.split("-")
                year = int(etime[0]) + int(record.year)
                yearstr = '-'
                etime[0] = str(year)
                retime = yearstr.join(etime)
                vip.e_time = retime
                db.session.add(vip)
            else:
                nowyear = datetime.date.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%m:%s")
                etime = nowyear.split("-")
                tyear = int(etime[0]) + int(record.year)
                etime[0] = str(tyear)
                yearstr = '-'
                retime = yearstr.join(etime)
                vip = Vip(userid=record.userid, s_time=datetime.datetime.now(), e_time=retime)
                db.session.commit(vip)
            db.session.commit()
        except:
            db.session.rollback()
    else:
        print('鉴权失败')
    return 'ok'


# 添加课程使用，获取标签，分类，类别
@user_blue.route("/getTags")
def getTags():
    tags = Tags.query.all()
    tagslist = [{"id":i.id,'name':i.name} for i in tags]
    types = Ctype.query.all()
    typeslist = [{'id':i.id,'name':i.name} for i in types]
    ctype = CourseType.query.all()
    clist = [{'id':i.id,'name':i.name} for i in ctype]
    return jsonify({
        "code":200,
        "tags":tagslist,
        'types':typeslist,
        "clist":clist
    })

from qiniu import Auth
# 获取七牛云token
@user_blue.route("/get_qntoken")
def get_qntoken():
    # -*- coding: utf-8 -*-
    # flake8: noqa



    #需要填写你的 Access Key 和 Secret Key
    access_key = 'YtYbdSuaeslVB1wDQNyG1Il0py1kSzJ0fX9bzOm5'
    secret_key = '3qPcPMATFz5SCgKfwOD0IuiyQ3eUzvq9xEmq6r2d'

    #构建鉴权对象
    q = Auth(access_key, secret_key)

    #要上传的空间
    bucket_name = 'h2205-yzl'



    #3600为token过期时间，秒为单位。3600等于一小时
    token = q.upload_token(bucket_name)

    return jsonify({
        "code":200,
        "token":token
    })

@user_blue.route('/addCourse',methods=['POST'])
def addCourse():
    try:
        # 获取参数
        data = json.loads(request.data)
        # 写入课程表
        course = Course(name=data['name'],url=data['url'],descrip=data['desc'],ctype=data['types'])
        db.session.add(course)
        # 获取新家的课程id
        scourse = Course.query.filter_by (name = data['name']).first()
        # 写入课程标签表
        for i in data['tags']:
            # 查询标签表
            tag = Tags.query.filter(Tags.id==i).first()
            scourse.tags.append(tag)
            # 原生sql
            # sql = 'insert into course_tag(courseid,tagid) values(%d,%d)'%(int(scourse.id),int(i))
            # db.session.execute(sql)
        # 课程分类表
        for i in data['ctype']:
            sql = "insert into course_cate(courseid,course_typeid) values(%d,%d)"%(int(scourse.id),int(i))
            db.session.execute(sql)
        db.session.commit()
        return jsonify({
            "code": 200,
            "mes":"添加成功"
        })
    except:
        db.session.rollback()
    return jsonify({
        "code":400,
        "mes":"添加失败"
    })




import math
@user_blue.route('/getCourse')
def getCourse():
    # 获取参数page
    page = int(request.args.get('page'))
    # 获取上线，即将上线
    online = int(request.args.get('is_publish'))
    # 获取分类
    types = int(request.args.get("types"))
    # 查询总条数
    if types == 0:
        total = Course.query.filter(Course.is_publish == online).count()
    else:
        total = Course.query.filter(Course.is_publish == online,Course.ctype == types).count()

    # 定义每页显示多少条
    page_size = 2
    # 查询当前页记录
    start = math.ceil((page-1)*page_size)
    # 原生sql
    # select * from course limit start,page_size

    # 获取排序字段
    orderpara = request.args.get('orderpara')
    if orderpara == 'new':
        if types == 0:
            course = Course.query.order_by(Course.create_time).filter(Course.is_publish == online).offset(start).limit(page_size).all()
        else:
            course = Course.query.order_by(Course.views).filter(Course.is_publish == online,Course.ctype==types).offset(start).limit(page_size).all()
    else:
        course = Course.query.order_by(Course.views).filter(Course.is_publish == online).offset(start).limit(page_size).all()

    list = [{"id":i.id,"name":i.name,"url":i.url,"views":i.views}for i in course]
    # 返回结果
    return jsonify({
        "code":200,
        "clist":list,
        "total":total,
        "page_size":page_size
    })



# 有错误
# @user_blue.route("/getCourse")
# def getCourse():
#     # 获取当前页面
#     page = int(request.args.get("page"))
#     page_size = 2
#     # 获取条件
#     # 获取上线，即将上线条件
#     online = int(request.args.get("is_publish"))
#     # 获取类别
#     types = int(request.args.get("types"))
#     # 获取类别
#     tags = int(request.args.get("tags"))
#     # 获取类别
#     orderpara = request.args.get("orderpara")
#     # 重构wher条件
#     where = "1=1"
#     if online:
#         where = where + "and c.is_publish=" + str(online)
#     if types > 0:
#         where = where + "and c.ctype=" + str(types)
#     # 排序
#     orderby = 'order by c.views desc'
#     if orderpara == 'new':
#         orderby = 'oredr by c.create_time desc'
#     start = math.ceil((page-1)*page_size)
#     # 查询一共有多少条记录
#     countsql = "select count(c.id) as tcount from course as c where "+where
#     cres = db.session.execute(countsql)
#     cdata = cres.fetchone()
#     total = cdata['tcount']
#     # 查询当前页记录
#     sql = "select c.* from course as c where"+where+orderby+" limit "+str(start)+","+str(page_size)
#     res = db.session.execute(sql)
#     data = res.fetchall()
#     clist = [{"id":i.id,"name":i.name,"url":i.url,"views":i.views}for i in data]
#     return jsonify({
#         "code":200,
#         "total":total,
#         "page_size":page_size,
#         "clist":clist
#     })